﻿using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using CommonUtil;
using Newtonsoft.Json.Linq;

namespace Client.Windows {
    /// <summary>
    /// CircleBall.xaml 的交互逻辑
    /// </summary>
    public partial class CircleBall : Window {
        readonly DragOverWindow dragOverWindow = DragOverWindow.GetDragOverWindow();
        readonly ShotScreen shotScreen = ShotScreen.GetShotScreen();
        readonly CNxMouseHook b = new CNxMouseHook();

        SocketUtil socket = SocketUtil.GetSocket();

        CircleBallViewModel dc = null;

        public CircleBall() {
            InitializeComponent();
        }

        public void Handle(Action fn) {
            var thread = new Thread(new ThreadStart(() => {
                Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate () {
                    fn();
                });
            }));
            thread.Start();
        }

        private void Grid_MouseDown(object sender, MouseButtonEventArgs e) {
            dragOverWindow.Hide();
            if (e.LeftButton == MouseButtonState.Pressed) {
                DragMove();
            }
        }

        private void Grid_DragEnter(object sender, DragEventArgs e) {
            CenterCircle.IsSide = false;
            dragOverWindow.Show();
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e) {
            MenuItem menuItem = (MenuItem)sender;
            switch (menuItem.Header) {
                case "打开客户端":
                    socket.Emit("openMainWindow");
                    break;
                case "隐藏悬浮球":
                    socket.Emit("hideLevitationball");
                    break;
                case "设置":
                    socket.Emit("openSetting");
                    break;
                case "截图":
                    shotScreen.Capture();
                    break;
                case "退出":
                    socket.Emit("quit");
                    break;
            }
        }

        private void Window_LocationChanged(object sender, EventArgs e) {
            if (Left < 0) Left = 0;
            else if (Left + Width > SystemParameters.WorkArea.Right) {
                Left = SystemParameters.WorkArea.Right - Width;
            }
            if (Top < 0) Top = 0;
            else if (Top + Height > SystemParameters.WorkArea.Bottom) {
                Top = SystemParameters.WorkArea.Bottom - Height;
            }
            Point WinPos = new Point(Left, Top);
            Properties.Settings.Default.WinPos = WinPos;
            Properties.Settings.Default.Save();
        }

        private void Circle_MouseEnter(object sender, MouseEventArgs e) {
            CenterCircle.IsSide = false;
            dragOverWindow.Show();
        }

        private void Circle_MouseLeave(object sender, MouseEventArgs e) {
            dragOverWindow.Hide();
            SetSide();
        }

        private void Grid_MouseUp(object sender, MouseButtonEventArgs e) {
            dragOverWindow.Show();
        }

        public void SetSide() {
            //double x = Left + (Width - CenterCircle.Width) / 2;
            //double w = CenterCircle.Width;
            CenterCircle.IsSide = Left + Width >= SystemParameters.PrimaryScreenWidth;
        }

        [DllImport("user32.dll", EntryPoint = "GetCursorPos")]
        public static extern int GetCursorPos(ref POINT lpPoint);

        private void Window_Loaded(object sender, RoutedEventArgs e) {
            socket = SocketUtil.GetSocket();
            dc = (CircleBallViewModel)DataContext;

            //dc.TotalCount = 10;
            //dc.LoadedCount = 5;

            socket.On("screenshot", (o) => {
                Console.WriteLine("截图");
                Handle(shotScreen.Capture);
                return null;
            });

            socket.On("showLevitationball", (o) => {
                Console.WriteLine("显示悬浮窗");
                Handle(Show);
                return null;
            });

            socket.On("hideLevitationball", (o) => {
                Console.WriteLine("隐藏悬浮窗");
                Handle(Hide);
                return null;
            });
            socket.On("processChange", (o) => {
                dynamic process = (JObject)o;
                dc.TotalCount = (int)process["TotalCount"];
                dc.LoadedCount = (int)process["LoadedCount"];
                return null;
            });
            socket.openSocket();

            //socket.Emit("Loaded");

            Point WinPos = Properties.Settings.Default.WinPos;

            if ((WinPos.X < 0) && (WinPos.Y < 0)) {
                Point a = SystemParameters.WorkArea.BottomRight;
                double x = a.X;
                double y = a.Y;

                Left = x - 200;
                Top = y - 340;
            } else {
                Left = WinPos.X;
                Top = WinPos.Y;
                SetSide();
            }
            b.MouseEvent += new MouseEventHandler((object sender1, MouseEventArgs e1) => {

                POINT myPoint = new POINT();
                GetCursorPos(ref myPoint);
                //LogUtil.Debug("鼠标坐标：" + myPoint.X + "," + myPoint.Y);

                if (IsInWindow(myPoint, "DragOverWindow")) return;
                Thread thread = new Thread(new ThreadStart(() => {
                    Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate () {
                        //LogUtil.Debug("监听到鼠标释放");
                        dragOverWindow.Hide();
                        SetSide();
                    });
                }));
                thread.Start();
            });
            b.Start();
        }

        private bool IsInWindow(POINT p, string winTitle) {
            Window window = GetWindowByTitle(winTitle);
            if (window == null) return false;
            return p.X >= window.Left && p.X <= window.Left + window.Width && p.Y >= window.Top && p.Y <= window.Top + window.Height;
        }

        private Window GetWindowByTitle(string title) {
            foreach (Window window in Application.Current.Windows) {
                if (title.Equals(window.Title)) {
                    return window;
                }
            }
            return null;
        }

        private void Window_Closed(object sender, EventArgs e) {
            LogUtil.logger.Info("悬浮窗被关闭");
            Application.Current.Shutdown();
        }

        //CenterCircle.Icon = new BitmapImage(new Uri("pack://application:,,,/Resources/CircleBall/excel.png", UriKind.RelativeOrAbsolute));
    }
    public struct POINT {
        public int X;
        public int Y;
        public POINT(int x, int y) {
            this.X = x;
            this.Y = y;
        }
    }
}
